import { h } from 'vue'
import axios from 'axios'
import qs from 'qs'
import config from '@/config'
import message from 'ant-design-vue/lib/message/index.js'
import Modal from 'ant-design-vue/lib/modal/index.js'
import { NETWORK_ERROR } from '@/constants/message.js'
import store from '@/store'

const service = axios.create({
  baseURL: config.API_BASE,
  timeout: 60000
})

const mockService = axios.create({
  baseURL: config.MOCK_BASE,
  timeout: 60000
})

// 请求拦截
service.interceptors.request.use(config => {
  const token = store.state.user.token
  if (token) {
    config.headers.Authorization = 'Bearer ' + token
  }
  if (window.location.pathname.match(/^\/client\/.+\//i)) {
    // 在client详细页面请求时header增加ccid
    const path = window.location.pathname
    const regex = /^\/client\/(.\d+)(\/?)/gim
    const match = regex.exec(path)
    if (Array.isArray(match) && match.length > 1) {
      config.headers.ccid = match[1]
    }
  }
  if (window.location.pathname.match(/^\/price\/.+/i)) {
    // 在价格页面请求时header增加apply
    const path = window.location.pathname
    const regex = /^\/price\/(.\d+)(\/?)/gim
    const match = regex.exec(path)
    if (Array.isArray(match) && match.length > 1) {
      config.headers.apply = match[1]
    }
  }
  return config
})

// 返回拦截
service.interceptors.response.use(
  response => {
    if (response.status === 401) {
      // 登录已过期
      store.dispatch('user/logout').then(() => {
        message.error('Authentication failed, Jump to Login after 5 seconds.', 5)
        setTimeout(() => {
          window.location.href = config.LOGIN_URL + window.location.href
        }, 5000)
      })
    } else if (response.data.code < 0) {
      switch (response.data.code) {
        case -1:
          // 无权限
          if (import.meta.env.DEV) {
            console.error('No Permission at ' + response.config.url)
          }
          return Promise.resolve({ data: { data: {}, noPermission: true } })
        case -2:
          // todo 参数错误
          message.error(response.data.message)
          break
        case -3:
          // todo 未授权
          message.error(response.data.message)
          break
        case -4:
          // todo 数据库操作失败
          message.error(response.data.message)
          break
        case -99: {
          const messages = response.data.message.split('$')
          const children = []
          messages.forEach((message, index) => {
            if (index > 0) {
              children.push(h('li', message))
            }
          })
          Modal.warning({
            title: messages[0],
            width: 754,
            content: h('ul', {}, children)
          })
          break
        }
        default:
          // todo 未知错误
          message.error(response.data.message)
      }
    } else {
      return Promise.resolve(response)
    }
  },
  error => {
    message.error(NETWORK_ERROR)
    return Promise.reject(error)
  }
)

/**
 * get方法，对应get请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 * @param mock 使用 mock
 * @param blob 二进制返回
 * @param headers
 */
export function get(url, params, mock = false, blob = false, headers = {}) {
  const instance = mock ? mockService : service
  const config = {}
  if (blob) {
    config.responseType = 'blob'
  }
  if (Object.keys(headers).length > 0) {
    config.headers = headers
  }
  config.params = params
  return new Promise((resolve, reject) => {
    instance
      .get(url, config)
      .then(res => {
        resolve(res.data)
      })
      .catch(err => {
        reject(new Error(err))
      })
  })
}

/**
 * post方法，对应post请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 * @param {String[]} type [请求数据类型，json(default)、form]
 * @param mock 使用 mock
 */
export function post(url, params, type = ['json'], mock = false) {
  const instance = mock ? mockService : service
  const config = {}
  return new Promise((resolve, reject) => {
    if (Array.isArray(type)) {
      if (type.includes('form')) {
        params = qs.stringify(params)
      }
      if (type.includes('fileForm')) {
        config.headers = { 'Content-Type': 'multipart/form-data' }
      }
      if (type.includes('blobResponse')) {
        config.responseType = 'blob'
      }
    }
    instance
      .post(url, params, config)
      .then(res => {
        resolve(res.data)
      })
      .catch(err => {
        reject(new Error(err))
      })
  })
}

/**
 * 文件上传
 */
export function upload(files, resolve, reject) {
  const uploadBox = new Eci.Control.UploadControl(
    {
      ws: config.SIGNAL_R_URL,
      IsRealName: false,
      fileNameSource: ' ',
      IsSingleProgress: true
    },
    {
      complete: function (data) {
        if (data.length > 0) {
          this.hide()
          resolve(data)
        }
      },
      close: function () {},
      error: function () {
        reject(new Error('Failed to connect to the server. Please try again later or contact administrator.'))
      }
    }
  )
  if (files.length && files.length > 0) {
    uploadBox.showUpload(files)
  }
}
